package com.atguigu.tingshu.search.service.impl;

import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.CategoryFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.BaseCategoryView;
import com.atguigu.tingshu.search.service.ItemService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class ItemServiceImpl implements ItemService {

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private CategoryFeignClient categoryFeignClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * @author WeakMoon
     * @date 2025/03/01 16:34:21
     * 专辑详情
     */
    @Override
    public Map<String, Object> getItem(Long albumId) {
        // 初始化一个HashMap用于存储专辑详情信息
        HashMap<String, Object> map = new HashMap<>();

        // 添加到布隆过滤器;
//        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
//        // 判断
//        if (!bloomFilter.contains(albumId)){
//             // 不包含就返回空对象
//             return map;
//        }

        // 异步获取专辑信息
        CompletableFuture<AlbumInfo> albumInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 调用专辑信息Feign客户端获取专辑信息
            Result<AlbumInfo> infoResult = albumInfoFeignClient.getAlbumInfo(albumId);

            // 断言调用结果不为空
            Assert.notNull(infoResult, "远程调用获取专辑列表信息失败");

            // 获取并断言专辑信息不为空
            AlbumInfo albumInfo = infoResult.getData();
            Assert.notNull(albumInfo, "远程调用专辑列表失败");

            // 将专辑信息放入map中
            map.put("albumInfo",albumInfo);

            // 返回数据
            return albumInfo;

        },threadPoolExecutor).exceptionally(ex -> {
            // 异常处理，打印异常信息并返回一个新的专辑信息对象
            System.out.println(ex.getMessage());
            return new AlbumInfo();
        });;

        // 异步获取分类视图信息
        CompletableFuture<Integer> categoryCompletableFuture = albumInfoCompletableFuture.thenApplyAsync(albumInfo -> {
            // 调用分类Feign客户端获取分类视图信息
            Result<BaseCategoryView> categoryViewResult = categoryFeignClient.getBaseCategoryView(albumInfo.getCategory3Id());

            // 断言调用结果不为空
            Assert.notNull(categoryViewResult, "远程调用获取分类视图失败");

            // 获取并断言分类视图信息不为空
            BaseCategoryView baseCategoryView = categoryViewResult.getData();
            Assert.notNull(baseCategoryView, "远程调用分类失败");

            // 将分类视图信息放入map中
            map.put("baseCategoryView", baseCategoryView);

            // 默认处理成功返回1
            return 1;

        },threadPoolExecutor).exceptionally(ex -> {
            // 异常处理，打印异常信息并返回0
            System.out.println(ex.getMessage());
            return 0;
        });

        // 异步获取用户信息
        CompletableFuture<Integer> userCompletableFuture = albumInfoCompletableFuture.thenApplyAsync(albumInfo -> {
            // 调用用户信息Feign客户端获取用户信息
            Result<UserInfoVo> infoVoResult = userInfoFeignClient.getUserInfo(albumInfo.getUserId());

            // 断言调用结果不为空
            Assert.notNull(infoVoResult, "远程调用用户信息失败");

            // 获取并断言用户信息不为空
            UserInfoVo userInfoVo = infoVoResult.getData();
            Assert.notNull(userInfoVo, "远程调用用户失败");

            // 将用户信息放入map中
            map.put("announcer", userInfoVo);

            // 默认处理成功返回1
            return 1;

        }, threadPoolExecutor).exceptionally(ex -> {
            // 异常处理，打印异常信息并返回0
            System.out.println(ex.getMessage());
            return 0;
        });

        // 异步获取统计值信息
        CompletableFuture<Integer> statCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 调用专辑信息Feign客户端获取统计值信息
            Result<AlbumStatVo> statVoResult = albumInfoFeignClient.getStat(albumId);

            // 断言调用结果不为空
            Assert.notNull(statVoResult, "远程调用获取统计值失败");

            // 获取并断言统计值信息不为空
            AlbumStatVo albumStatVo = statVoResult.getData();
            Assert.notNull(albumStatVo, "远程调用统计值失败");

            // 将统计值信息放入map中
            map.put("albumStatVo", albumStatVo);

            // 默认处理成功返回1
            return 1;

        }, threadPoolExecutor).exceptionally(ex -> {
            // 异常处理，打印异常信息并返回0
            System.out.println(ex.getMessage());
            return 0;
        });

        // 同步等待所有异步任务完成
        try {
            if (albumInfoCompletableFuture.get() == null || categoryCompletableFuture.get() == 0 ||
                    userCompletableFuture.get() == 0 || statCompletableFuture.get() == 0){
                return map;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        // 确保所有异步任务都已完成
        CompletableFuture.allOf(
                albumInfoCompletableFuture,
                categoryCompletableFuture,
                userCompletableFuture,
                statCompletableFuture).join();

        return map;
    }
}
